#!/usr/bin/bash

LISTEN_CMD="./server.sh listen"

#服务列表, 单词间要用1个空格
SERVERS_LIST=(
"./run.sh ndlogs ndlogs"
"./run.sh ndgame ndmatch"
"./run.sh ndgame ndtexas"
"./run.sh ndadmin ndadmin"
#"./run.sh ndbot ndbot"
"./run.sh ndgame ndbilliard"

)



function echo_red()
{
  content=$*
  echo -e "\033[41;36m 错误：$content \033[0m"
}
s
function expect_yes()
{
  read -p "是否继续?(Y/N):" opt
  opt="${opt:-N}"
  echo $opt
  if [ $opt != "Y" ]; then
      exit 0
  fi
  return 1
}


#使用说明
function usage()
{
  echo "使用参考:"
  echo "$g_script stop|restart|update|status|listen|stop_listen|version [ keyworld1 keyworld2 ...]"
  echo "依据关键词检索服务列表，举例："
  echo "开启所有服务：$g_script star run"
  echo "关闭所有服务：$g_script stop run"
  echo "开启服务：$g_script star ndgame"
  echo "关闭服务：$g_script stop ndgame"
  echo "重启所有服务：$g_script restart run" #run代表全部节点
  echo "开启监听：$g_script listen"
  echo "停止监听：$g_script stop_listen"

}

#检查参数个数
function check_params()
{
  if [ -z "$g_params" ]; then
          echo "缺少参数2"
          usage
          exit -1
  fi
}

#如果进程名字有与参数是包含关系则返回1, 不存在返回0
function filter_item()
{
  server=$1 #节点名
  #echo $server
  #echo $g_params
  for param in $g_params;
  do
    #echo "$server" | grep -w $param
    server=`echo "$server" | grep $param`
    #echo $param "==fiter out==>" $server
  done
  if [ -z "$server" ]; then
    #echo "un-matched------>$SERVERS_LIST"
    return 0
  fi
  return 1
}

function start_()
{
    cd ./tools
    pwd
    for i in "${!SERVERS_LIST[@]}";
    do
        item=${SERVERS_LIST[$i]}
        filter_item "$item"
        if [ $? -eq 1 ]; then
          echo $item
          node_name=`echo "$item" | cut -d ' ' -f 3` #取最后一个单词
          result=`ps -lef |grep skynet |grep "$node_name"|grep -v grep`
          if [ -z "$result" ]; then
              #将标准错误输出 2 也重定向到了标准输出 1 中, &在后台运行
              $item >> /home/logs/output.log 2>&1 &
          fi
        fi
#        echo "222222222"
    done
    cd ../
}

function stop_()
{
  for i in "${!SERVERS_LIST[@]}";
  do
      item=${SERVERS_LIST[$i]}
      filter_item "$item"
      if [ $? -eq 1 ]; then
          node_name=`echo "$item" | cut -d ' ' -f 3` #取最后一个单词
          result=`ps -lef |grep skynet |grep "$node_name"|grep -v grep`
          if [ -n "$result" ]; then
              ps -lef |grep skynet |grep "$node_name"|grep -v grep|awk '{print $4}'|xargs kill -9
          fi
      fi
  done

}







#查看状态
function status()
{
  title=$1
  echo "----------------------------------------------------------------$title-----------------------------------------------------------------------------"
  ps -lef |head -1 #ps表头显示下

  matched_count=0
  started_count=0
  for i in "${!SERVERS_LIST[@]}";
  do
    item=${SERVERS_LIST[$i]}
#    echo $item
    filter_item "$item" #过滤
    if [ $? -eq 1 ]; then
        let matched_count+=1
        node_name=`echo "$item" | cut -d ' ' -f 3` #取最后一个单词
#        echo $node_name
        ps -lef |grep skynet|grep "$node_name" |grep -v grep
        result=`ps -lef |grep skynet|grep "$node_name"|grep -v grep`
        if [ -n "$result" ]; then
            let started_count+=1
        else
            echo_red "进程未启动:$item"
        fi
    fi
  done
  result=0
  if [ $matched_count -le 0 ]; then
    echo_red "未找到匹配项，请检查搜索条件或补充服务列表"
    result=0
  elif [ $started_count -le 0 ]; then
    echo_red "进程全都没启动"
    result=1
  elif [ $started_count -lt $matched_count ]; then
    echo_red "进程没有全部启动"
    result=1
  elif [ $started_count -ge $matched_count ]; then
    echo "进程已全部启动"
    result=2
  fi

  echo "----------------------------------------------------------------------------------------------------------------------------------------------------"
  return $result
}


function stop()
{
    status "停服前"
    echo "你正在执行停服操作"
    expect_yes
    stop_
    status "停服后"

}

function start()
{
  status "启动前"
  result=$?
  if [ $result -eq 0 ]; then
    echo_red "脚本已终止运行"
    exit 0
  fi
  if [ $result -eq 2 ]; then
    echo "无需重复启动"
    exit 0
  fi
  expect_yes
  echo "正在执行启动操作"
  start_
  sleep 1
  status "启动后"
}

function print_servers()
{
  echo "节点列表:"
  for i in "${!SERVERS_LIST[@]}";
  do
      echo "[${SERVERS_LIST[$i]}]"
  done

  status "已运行的节点"
}

function start_listen()
{
  echo "开启监听"
  result=`ps -lef |grep "$LISTEN_CMD" |grep -v grep`
  if [ -z "$result" ];then
    nohup $LISTEN_CMD > /dev/null &
  fi
}

function stop_listen()
{
  echo "关闭监听"
  result=`ps -lef |grep "$LISTEN_CMD" |grep -v grep|awk '{print $4}' `
  if [ -n "$result" ];then
    kill -9 $result
  fi
}

function restart()
{
  stop_listen

  status "重启前"
  result=$?
  if [ $result -eq 0 ]; then
          echo_red "脚本已终止运行"
          exit -1
  fi

  echo "Step1:停服"
  echo "你正在执行重启操作"
  expect_yes
  if [ $? -ne 1 ]; then
     set -e
  fi
  stop_
  echo "Step2:启服"
  start_
  sleep 3
  status "重启后"

  start_listen #监听进程，挂了重启
}


function listen_once()
{
  for i in "${!SERVERS_LIST[@]}";
  do
    item=${SERVERS_LIST[$i]}
    node_name=`echo "$item" | cut -d ' ' -f 3`
    result=`ps -lef |grep skynet|grep "$node_name"|grep -v grep`
    if [ -z "$result" ]; then
        echo "新启进程：$item"
        eval "$item  > /dev/null"
    fi
  done
}


function listen()
{
    while true; do
        #listen和listen_分离是因为想重新加载./server.sh脚本，防止服务列表有更新
        ./server.sh listen_once
        sleep 10
    done
}

function hotfix()
{
    cd ./tools
    pwd
    for i in "${!SERVERS_LIST[@]}";
    do
        item=${SERVERS_LIST[$i]}
        filter_item "$item"
        if [ $? -eq 1 ]; then
          node_name=`echo "$item" | cut -d ' ' -f 3` #取最后一个单词
          echo node_name:$node_name
          python hotfix.py "$node_name"
        fi
    done
    cd ../
}







#初始化全局变量
g_script=$0 #脚本名
g_command=$1 #第一个参数
g_params=`echo $*` #所有的参数
#echo $g_params
g_params=`echo ${g_params#$g_command}` #把g_command从串中删除
#echo $g_params

####################################

case $1 in
  "status")
    status "查看状态"
    ;;
  "stop")
    check_params
    stop
    ;;
  "start")
    check_params
    start
    ;;
  "print")
    print_servers
    ;;
  "listen")
    listen
    ;;
  "stop_listen")
    stop_listen
    ;;
  "restart")
    check_params
    restart
    ;;
  "hotfix")
    hotfix
    ;;

  *)
    usage
    ;;
esac